#include <iostream>
#include <memory>
#include <fstream>
#include "viml/vm.h"
#include "viml/debugger.h"
#include "viml/debug_info.h"
#include "viml/compiler.h"
#include "viml/debugger_cli.h"

using namespace viml;

// 简化的测试，不使用readline以避免依赖问题
class SimpleDebuggerCLI {
private:
    std::shared_ptr<VM> vm;
    std::shared_ptr<Debugger> debugger;
    std::shared_ptr<DebugInfo> debug_info;
    bool is_running;

public:
    SimpleDebuggerCLI(std::shared_ptr<VM> virtual_machine)
        : vm(virtual_machine), is_running(false) {
        debugger = std::make_shared<Debugger>(vm);
        debug_info = std::make_shared<DebugInfo>();
        debugger->set_debug_info(debug_info);
        vm->set_debugger(debugger);
    }

    void run_interactive() {
        std::cout << "\n=== VimL 简化调试器 ===\n";
        std::cout << "可用命令:\n";
        std::cout << "  help     - 显示帮助\n";
        std::cout << "  quit     - 退出调试器\n";
        std::cout << "  continue - 继续执行\n";
        std::cout << "  step     - 单步执行\n";
        std::cout << "  break    - 设置断点 (break <行号>)\n";
        std::cout << "  list     - 显示断点\n";
        std::cout << "  where    - 显示当前位置\n";
        std::cout << "  locals   - 显示局部变量\n";
        std::cout << "========================\n";

        // 设置一些测试断点
        std::cout << "设置测试断点...\n";
        debugger->set_breakpoint(8);  // 在变量赋值处
        debugger->set_breakpoint(15); // 在echo语句处

        debugger->start();
        is_running = true;

        std::string command;
        while (is_running) {
            std::cout << "(dbg) ";
            std::getline(std::cin, command);

            if (command.empty()) continue;

            // 简单的命令解析
            if (command == "quit" || command == "q") {
                std::cout << "退出调试器\n";
                is_running = false;
            } else if (command == "help" || command == "h") {
                show_help();
            } else if (command == "continue" || command == "c") {
                std::cout << "继续执行程序...\n";
                debugger->resume();
                is_running = false;  // 让程序运行
            } else if (command == "step" || command == "s") {
                std::cout << "单步执行...\n";
                debugger->step_into();
            } else if (command == "break" || command == "b") {
                // 简化实现：解析 "break <行号>"
                size_t space_pos = command.find(' ');
                if (space_pos != std::string::npos && space_pos + 1 < command.length()) {
                    std::string line_str = command.substr(space_pos + 1);
                    try {
                        int line = std::stoi(line_str);
                        debugger->set_breakpoint(line);
                        std::cout << "设置断点在第 " << line << " 行\n";
                    } catch (const std::exception& e) {
                        std::cout << "错误: 无效的行号\n";
                    }
                } else {
                    std::cout << "用法: break <行号>\n";
                }
            } else if (command == "list" || command == "l") {
                auto breakpoints = debugger->get_all_breakpoints();
                std::cout << "断点列表:\n";
                for (const auto* bp : breakpoints) {
                    std::cout << "  断点 " << bp->id << ": 第 " << bp->location.line << " 行";
                    if (!bp->enabled) {
                        std::cout << " (禁用)";
                    }
                    std::cout << "\n";
                }
                if (breakpoints.empty()) {
                    std::cout << "  无断点\n";
                }
            } else if (command == "where" || command == "w") {
                int line = debugger->get_current_line();
                std::cout << "当前位置: 第 " << line << " 行\n";
                if (debug_info) {
                    std::string source_line = debug_info->get_source_line(line);
                    if (!source_line.empty()) {
                        std::cout << "源码: " << source_line << "\n";
                    }
                }
            } else if (command == "locals" || command == "ls") {
                auto variables = debugger->get_all_variables();
                std::cout << "局部变量:\n";
                for (const auto& pair : variables) {
                    std::cout << "  " << pair.first << " = " << pair.second.to_string() << "\n";
                }
                if (variables.empty()) {
                    std::cout << "  无局部变量\n";
                }
            } else {
                std::cout << "未知命令: " << command << "\n";
                std::cout << "输入 'help' 获取可用命令\n";
            }
        }
    }

    void show_help() {
        std::cout << "\n命令说明:\n";
        std::cout << "  help, h     - 显示此帮助信息\n";
        std::cout << "  quit, q     - 退出调试器\n";
        std::cout << "  continue, c - 继续执行程序直到下一个断点\n";
        std::cout << "  step, s     - 单步执行下一条指令\n";
        std::cout << "  break, b    - 在指定行设置断点\n";
        std::cout << "                用法: break <行号>\n";
        std::cout << "  list, l     - 显示所有断点\n";
        std::cout << "  where, w   - 显示当前位置和源码\n";
        std::cout << "  locals, ls - 显示当前作用域的变量\n";
        std::cout << "\n示例:\n";
        std::cout << "  break 15    # 在第15行设置断点\n";
        std::cout << "  step        # 单步执行\n";
        std::cout << "  continue    # 继续执行\n";
        std::cout << "  where       # 显示当前位置\n";
        std::cout << "\n";
    }

    bool load_and_run(const std::string& filename) {
        std::ifstream file(filename);
        if (!file.is_open()) {
            std::cerr << "错误: 无法打开文件 " << filename << std::endl;
            return false;
        }

        std::cout << "加载文件: " << filename << "\n";

        // 读取文件内容
        std::string source((std::istreambuf_iterator<char>(file)),
                           std::istreambuf_iterator<char>());

        // 编译
        auto compiler = std::make_unique<Compiler>();
        auto bytecode = compiler->compile(source, filename);
        if (!bytecode) {
            std::cerr << "错误: 编译失败\n";
            return false;
        }

        std::cout << "编译成功！\n";

        // 设置调试信息
        debug_info->set_source_file(filename);
        debug_info->load_source_file();

        // 执行
        std::cout << "启动调试器...\n\n";
        run_interactive();

        return true;
    }
};

int main(int argc, char* argv[]) {
    std::cout << "VimL CLI调试器测试程序\n";

    if (argc != 2) {
        std::cout << "用法: " << argv[0] << " <VimL脚本文件>\n";
        std::cout << "示例: " << argv[0] << " example/hello.vim\n";
        return 1;
    }

    std::string filename = argv[1];

    try {
        // 创建虚拟机
        auto vm = std::make_shared<VM>();

        // 创建调试器CLI
        SimpleDebuggerCLI debugger_cli(vm);

        // 加载并运行文件
        return debugger_cli.load_and_run(filename) ? 0 : 1;

    } catch (const std::exception& e) {
        std::cerr << "错误: " << e.what() << std::endl;
        return 1;
    }
}